1 导入bootstrap样式
在index.html中引入：
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">

2 将未定义地址重定向到index页面
{
        path: '*',
        redirect: {name:'index'}
    }

3 字符串截取方法
// 获取字符串最后一个/的index
    let index = str.lastIndexOf('/')
// 获取index字符
    let val = str.substring(index + 1, str.length)
// 截取index前面的字符
       str.substring(index, -1)

4 element-ui 验证表单需要prop的名称来确定，否则无法识别
prop="username"

5 过滤器minxins写法
先封装minxins/common.js
export default {
    filters: {
        // 将数字转为字符串
        numToString(num) {
          return num.toString()
        }
      }
}
在组件中调用
import common from "@/common/mixins/common";
mixins: [common]
使用时
:index="index|numToString"

6 当前页面路由路径信息
this.$route.matched

7 监听路由变化 当跳转到index时 面包屑导航消失 这是由getRouterBran函数定义的
watch: {
    // 监听路由变化
    '$route'(to, from) {
      this.getRouterBran()
    }
  },

8 路由报重复错误
在router/index.js中添加如下：
//获取原型对象上的push函数
const originalPush = VueRouter.prototype.push
//修改原型对象中的push方法
VueRouter.prototype.push = function push(location) {
   return originalPush.call(this, location).catch(err => err)
}

9 动态绑定多个元素 用数组形式
:class="[item.icon, item.bac]"

10 vue引入echarts应使用
import * as echarts from 'echarts';
不能直接用下面这种，会报错
import echarts from 'echarts';

11 flex布局中第一个写上 margin-right auto
后面的元素会自动到最右边

12 el-submenu 的下一级菜单 需设置相应的操作动作 否则会出错
<el-menu-item index="6-1">修改</el-menu-item>
<el-menu-item index="6-2">退出</el-menu-item>
handleSelect(key, keyPath) {
      // 如果是点击头像下一级的菜单栏就要执行相应的动作
      if (key === "6-1") {
        return console.log(key);
      } else if (key === "6-2") {
        return console.log(key);
      } else {
        // 先获取顶部导航栏选择key值
        this.navBar.active = key;
        // 点击顶部导航栏后将侧边导航重置
        this.slideMenusActive = "0";
        if (this.slideMenus.length) {
          this.$router.push({
            name: this.slideMenus[this.slideMenusActive].pathname,
          });
        }
      }
    },

13 下拉菜单点击删除需要加上native，点击才会生效
<el-dropdown-item
@click.stop.native="albumsDel(index)"
>删除</el-dropdown-item>

14 分栏布局响应式
<el-row :gutter="10">
  <el-col
  :span="24"
  :lg="4"
  :md="6"
  :sm="8"
  >
  </el-col>
</el-row>

15 v-slot='scope'
scope.$index 是当前商品的索引值

16 el-radio-group 组合控制数值变化 事件采用@input 方式
:value 绑定的值和下面的label保持一致 $event可接收下面传来的label值
<el-radio-group :value='skus_type' @input="vModel({key: 'skus_type', value: $event})" 
size="mini">
  <el-radio-button :label="0">单一规格</el-radio-button>
  <el-radio-button :label="1">多规格</el-radio-button>
</el-radio-group>

17 涉及到多个值时  最好以对象形式传参
// 删除指定卡片的规格属性
delSkuValue(state, {cardIndex, valueIndex}) {
    state.sku_card[cardIndex].list.splice(valueIndex, 1)
}

18 拖曳排序插件 npm网站
npm install awe-dnd --save

<SkuCardChildren v-for="(item2, index2) in list" :key="index2" 
:type="item.type" :item='item2' :cardIndex='index' :index='index2'
v-dragging="{ item: item2, list: list, group: `skuItem${index}` }"
></SkuCardChildren>

mounted () {
      // 监听拖曳结束
      this.$dragging.$on('dragend', (e) => {
        console.log(e);
        if (e.group === 'skuItem' + this.index) {
          this.sortSkuValue({
          index: this.index,
          value: this.list
          })
        console.log(this.list);
        }
      })

item 是当前对象 list 是属性列表 group是自定义的组


19 vuex分模块中的state记住要通过对象形式才能访问
但mapGetters和mutations等不需要
比如：
computed:{
 ...mapGetters(['table_ths']),
 ...mapState({
     sku_card: state => state.goods_create.sku_card
})

20 getters中需要state中的数据
skuLabels(state) {}
getters中需要getters中的数据
table_ths(state, getters) {}

21 依赖注入方法
在App.vue 中定义选择图片对话框 所有组件都可以通过依赖注入拿到
App.vue 中，将name定义为app:
// 依赖注入
  provide: function () {
      return {
        app: this
      }
    },
子组件中
inject: ['app'],
就可以通过this.app 调用App.vue 中的方法

22 性能优化
选用v-if尽量使用原生标签，避免使用库 响应会更快

23 批量删除选定的图片
imgDelAll() {
  let list = this.imgList.filter(img => {
    return !this.chooseList.some(c => {
      return c.id === img.id
      })
    })
}

24 取消选择图片
    unChoose() {
      this.imgList.forEach(img => {
        // 找到选择列表有的图片的索引
        let i = this.chooseList.findIndex(v => {
          return v.id === img.id
        })
        if (i > -1) {
          // 从选择列表中删除
          this.chooseList.splice(i,1)
          img.isCheck = false
          img.checkOrder = 0
        }
      })
    }

25 
app.vue 中可以将max传到子组件中
show(callback, max = 9) {
      this.maxChooseImage = max
      // 调用子组件方法
      this.$refs.imageDialog.show(callback)
    }

同时调用app.vue 中方法的也可以通过这种形式传入max的值
choose() {
     this.app.show(res => {
         console.log(res);
     },3)
 }

 26 富文本编辑器tinymce安装
 npm i tinymce -S
 npm install '@tinymce/tinymce-vue@3.0.1' -S
 建立中文语言包和皮肤
 public/tinymce/zh_CN.js
 public/skins
 新建tinymce.vue 文件

问题1：vue使用tinymce中提示Object(...) is not a function
版本太高了，vue2中不能使用@tinymce/tinymce-vue为4以上版本；
所以卸载以前的：npm uninstall @tinymce/tinymce-vue
安装低版本的：例如：npm install @tinymce/tinymce-vue@3.0.1 -S

问题2 报错Uncaught SyntaxError: Unexpected token '<'
在tinymce.vue 中增加以下引入
import 'tinymce/icons/default/icons'

27 如果在数组中需要遍历其中的一部分属性，可以通过计算属性以一定条件筛选出来再遍历.

28 if 判断语句注意
在条件符合时的代码 如果后面没有接else 而是直接写不符合条件的代码
需要在条件符合的代码执行完后return 否则会直接继续执行后面的代码
要么用if else  或者加return

29 使用过滤器 要将数据使用插槽方式
<template v-slot="scope">
  {{scope.row.value_list | getValue}}
</template>

30 el-table 数据引用对象内部的数组如果不显示 则需要将其取到外部